package doublecheckdemo;

/**
 * @ClassName DoubleCheckSingleton
 * @Description 双重检查的单例模式
 * @Author 高达磊
 * @Date 2022/1/11-21:59
 * @Version 1.0
 */
public class DoubleCheckSingleton {

    // 使用volatile关键字避免指令重排问题和可见性。
    private static volatile DoubleCheckSingleton INSTANCE;

    private DoubleCheckSingleton() {
    }

    /**
     * 通过双重检查减少多线程时的线程阻塞问题，但是并没有完全解决
     * 部分线程在排队后直接返回，部分线程在进入该方法后的第一个判断直接返回。
     * 如果是同步方法，那么不管对象是否创建，都需要在方法入口外排队等待。
     *
     * @return
     */
    public static DoubleCheckSingleton getInstance() {

        if (null == INSTANCE) {
            synchronized (DoubleCheckSingleton.class) {
                if (null == INSTANCE) {
                    INSTANCE = new DoubleCheckSingleton();
                }
            }
        }

        return INSTANCE;
    }
}
